package com.hjk.common.utils.aop;

import com.hjk.common.utils.check.Check;
import com.hjk.common.utils.string.JsonUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.junit.Test;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 切面相关工具类
 *
 * @author huangjunkai
 * @version 1.0
 * @date 2019/7/15 12:49
 */
public class AopUtils {

    /**
     * 拼接请求参数不为空的
     *
     * @param point ProceedingJoinPoint
     * @return com.hjk.common.utils.Aop.SpringAopUtils#getFullMethodName(org.aspectj.lang.ProceedingJoinPoint)
     */
    @Deprecated
    public static String getFullMethodName(ProceedingJoinPoint point) {
        String fullMethodName = "%s#%s(%s)";
        //类名
        String className = point.getTarget().getClass().getName();
        //方法名
        String methodName = point.getSignature().getName();
        //参数名

        Object[] args = point.getArgs();
        String paramJson = args.length > 0 && args[0] != null ? Arrays
                .stream(args)
                .filter(Check::isNotEmpty)
                .map(m -> m.getClass().getName())
                .collect(Collectors.joining(",")) : "";
        return String.format(fullMethodName, className, methodName, paramJson);

    }

    /**
     * 获取全限定方法名
     *
     * @param point ProceedingJoinPoint
     * @return public static void com.hjk.main(java.lang.String[])
     */
    public static String getMethodName(ProceedingJoinPoint point) {
        try {
            return Arrays.stream(point.getTarget().getClass().getMethods()).filter(f -> f.getName().equals(point.getSignature().getName())).findFirst().get().toString();
        } catch (Exception ignored) {

        }
        return "";
    }


    /**
     * 获取方法上的注解
     */
    public static <T extends Annotation> T getAnnotation(JoinPoint joinPoint, Class<T> annotationClass) {
        Method[] methods = joinPoint.getTarget().getClass().getDeclaredMethods();
        String methodName = joinPoint.getSignature().getName();

        return Arrays.stream(methods)
                .map(m -> {
                    T anno = m.getAnnotation(annotationClass);
                    return Objects.nonNull(anno) && methodName.equals(m.getName()) ? anno : null;
                })
                .filter(Objects::nonNull)
                .findFirst()
                .orElse(null);
    }


    /**
     * 获取HttpServletRequest
     */
    public static HttpServletRequest getHttpServletRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    public static String getDomain() {
        HttpServletRequest request = getHttpServletRequest();
        StringBuffer url = request.getRequestURL();
        return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
    }

    public static String getUserAgent() {
        return getHttpServletRequest().getHeader(HttpHeaders.USER_AGENT);
    }


    public static String getOrigin() {
        HttpServletRequest request = getHttpServletRequest();
        return request.getHeader(HttpHeaders.ORIGIN);
    }

    /**
     * 获取请求参数
     *
     * @param request:   request
     * @param joinPoint: joinPoint
     * @return java.lang.String
     */
    private String getRequestParams(HttpServletRequest request, JoinPoint joinPoint) {
        String httpMethod = request.getMethod();
        String params = "";
        if ("POST".equals(httpMethod) || "PUT".equals(httpMethod) || "PATCH".equals(httpMethod)) {
            Object[] paramsArray = joinPoint.getArgs();
            params = JsonUtils.jsonFormat(paramsArray);
        } else {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            // 请求的方法参数值
            Object[] args = joinPoint.getArgs();
            // 请求的方法参数名称
            LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
            String[] paramNames = u.getParameterNames(method);
            if (args != null && paramNames != null) {
                for (int i = 0; i < args.length; i++) {
                    params += "  " + paramNames[i] + ": " + args[i];
                }
            }
        }
        return params;
    }

    public static void main(String[] args) {
        try {
            int i = 1 / 0;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            System.out.println("hhhhhhhhhhhhhhh");
        }
    }


}
